#include "stdafx.h"
#include "FileStream.h"

using namespace System;
using namespace IO;
using namespace Exception;

//FileStream::FileStream(LPCWSTR fileName, bool write , bool append , bool create )
//{
//	size_t origsize = wcslen(fileName) + 1;
//	const size_t newsize = 266;
//	size_t convertedChars = 0;
//	char nstring[newsize];
//	wcstombs_s(&convertedChars, nstring, origsize, fileName, _TRUNCATE);
//	FileStream(nstring, write, append, create);
//
//}
FileStream::FileStream(LPCWSTR fileName, bool write, bool append, bool create)
{
#ifdef WIN32 
	//first construct params;
	LPCWSTR lpFileName				= fileName;
	DWORD dwDesiredAccess			= write ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ;
	DWORD dwShareMode				=	0;
	LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL;
	DWORD dwCreationDisposition		= create ? CREATE_ALWAYS : OPEN_EXISTING;
	DWORD dwFlagsAndAttributes		= FILE_ATTRIBUTE_NORMAL;
	HANDLE hTemplateFile			= NULL;
	
	m_handle = CreateFileW(
						lpFileName,
						dwDesiredAccess,
						dwShareMode,
						lpSecurityAttributes,
						dwCreationDisposition,
						dwFlagsAndAttributes,
						hTemplateFile
					);
	DWORD err = GetLastError();
	switch (err)
	{
	case 0xB7:
	{
		//truncate the file
		CloseHandle (m_handle);
		dwCreationDisposition	= TRUNCATE_EXISTING;
		m_handle = CreateFileW(
						lpFileName,
						dwDesiredAccess,
						dwShareMode,
						lpSecurityAttributes,
						dwCreationDisposition,
						dwFlagsAndAttributes,
						hTemplateFile
					);
		DWORD err2 = GetLastError();
		if (err2 != ERROR_SUCCESS)
		{
			throw(Exception::IOFileException(L"Error opening file"));
		}
	}

		break;
	default:
		throw(Exception::IOFileException(L"Error opening file"));
	}
		
#else

#endif
}

FileStream::~FileStream()
{
#ifdef WIN32
	CloseHandle(m_handle);
#else

#endif
}

int   FileStream::read(MemoryBuffer& memBuf, int offset, size_t count)
{
#ifdef WIN32
	DWORD bytes;
	memBuf.updateSize(count);
	int	nRet = ReadFile(m_handle, memBuf.getData(), (DWORD)count, &bytes, 0);
	
	if(!nRet)
	{
		throw new IOFileException();
		//return GetLastError();
	}

	return bytes;
#else
	return 0;
#endif
}

int   FileStream::readByte(byte& value)
{
#ifdef WIN32
	DWORD bytes;
	int	nRet = ReadFile(m_handle, &value, 1, &bytes, 0);
	
	if(!nRet)
	{
		throw new IOFileException();
		//return GetLastError();
	}
    
	return bytes;
#else
	return 0;
#endif
}

ud_uint64  FileStream::seek(ud_uint64 offset, SeekOrigin origin)
{
#ifdef WIN32
	LARGE_INTEGER		sectorPos;
	sectorPos.QuadPart	=	offset;

	DWORD crtFilePtr = SetFilePointer(m_handle, sectorPos.LowPart, &sectorPos.HighPart, FILE_BEGIN);	
	
	return crtFilePtr;
#else
	return 0;
#endif
}

void  FileStream::setLength(ud_uint64 value)
{	
	throw Exception::IOFileException(L"Do you really want to set length on a file?!");
}

int  FileStream::write(const MemoryBuffer& memBuf, int offset, size_t count)
{
	if (!count)
	{
		count = memBuf.size();
	}
#ifdef WIN32
	DWORD bytes = 0;
	byte* data = memBuf.getData();
	DWORD nRet = WriteFile(m_handle, data, (DWORD)count, &bytes, NULL);
	DWORD err = GetLastError();
	if(err != ERROR_SUCCESS)
		throw(Exception::IOFileException(L"Error writing to file"));
	return bytes;
#else
#endif
}

void  FileStream::writeByte(byte value)
{
#ifdef WIN32
	DWORD bytes = 0;
	DWORD nRet = WriteFile(m_handle, &value, 1, &bytes, NULL);
#else
#endif
}
